package com.oro.domain;

import static javax.persistence.CascadeType.ALL;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Transient;

import org.hibernate.validator.NotNull;

/**
 * Entity implementation class for Entity: Scuola
 * 
 */
@Entity
public class Scuola implements Serializable {

	private static final long serialVersionUID = 1L;

	private String abn;
	private String bankAccountNumber;
	private String bsb;
	private String spiftCode;
	private String bankName;
	private String intestatarioContoFirstName;
	private String intestatarioContoMiddleName;
	private String intestatarioContoSurname;
	private String nationalProvider;
	private String providerCode;

	@ManyToOne(cascade = ALL)
	// uni-directional
	@JoinTable(name = "scuola_banca")
	private Banca bank;

	@ManyToOne(cascade = ALL)
	// uni-directional
	@JoinTable(name = "scuola_filialebanca")
	private BankBranch bankBranch;

	@ManyToOne(cascade = ALL)
	@JoinTable(name = "scuola_adder")
	private User adder;

	@OneToMany(mappedBy = "school", cascade = ALL)
	private List<Sede> branches;

	@Transient
	private Sede branchToRemove;

	// @NotNull
	private String code;

	@Transient
	private Contatto contactToRemove;

	@OneToMany(mappedBy = "school", cascade = ALL)
	private List<ContattoScuola> contattiDiRiferimento;

	@NotNull
	private boolean contrattoInCorso;

	@OneToMany(mappedBy = "school", cascade = ALL)
	private List<Corso> courses;

	@Transient
	private Corso courseToRemove;

	private String cricosProviderCode;

	private String elicosCode;

	@OneToMany(cascade = ALL)
	@JoinTable
	private List<Email> emails;

	@OneToMany(cascade = ALL)
	@JoinTable
	private List<Fax> faxes;

	@Id
	@GeneratedValue
	private Long id;

	@OneToOne(cascade = ALL)
	@JoinTable(name = "scuola_indirizzo")
	// Uni-directional
	private Indirizzo indirizzo; // For extensibility, in case the business
									// would include USA or Canadian schools.

	private Date insertionDate;

	@NotNull
	private String ragioneSociale;

	@OneToOne(cascade = ALL)
	@JoinTable(name = "scuola_materialestudio")
	private MaterialeStudio studyMaterial;
	@OneToMany(cascade = ALL)
	@JoinTable
	private List<Telephone> telephones;
	private String webSite;

	public Scuola() {
		super();
		indirizzo = new IndirizzoAU();
		setContattiDiRiferimento(new ArrayList<ContattoScuola>());
		setEmails(new ArrayList<Email>());
		setTelephones(new ArrayList<Telephone>());
		setFaxes(new ArrayList<Fax>());
		setBranches(new ArrayList<Sede>());
		setCourses(new ArrayList<Corso>());
		studyMaterial = new MaterialeStudio();
	}

	public Scuola(String nome) {
		this(nome, false);
	}

	public Scuola(String nome, boolean inCorso) {
		this();
		this.ragioneSociale = nome;
		this.contrattoInCorso = inCorso;
	}

	public boolean add(ContattoScuola c) {
		// return emails.add(email); // this does not work
		if (c == null)
			return false;
		if (this.has(c))
			return false;
		contattiDiRiferimento.add(c);
		return true;
	}

	public boolean add(Email email) {
		// return emails.add(email); // this does not work
		if (this.has(email))
			return false;
		emails.add(email);
		return true;
	}

	public boolean add(Fax fax) {
		if (this.has(fax))
			return false;
		faxes.add(fax);
		return true;
	}

	public boolean add(Sede sede) {
		// TODO: add checks before adding
		return branches.add(sede);
	}

	public boolean add(Telephone tel) {
		if (this.has(tel))
			return false;
		telephones.add(tel);
		return true;
	}
	
	public int getNumCourses() {
		return getCourses().size();
	}

	@Override
	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (o != null)
			if (o instanceof Scuola)
				if (id != null && id != 0L)
					return id.equals(((Scuola) o).getId());
				else
					return this.getIndirizzo().equals(
							((Scuola) o).getIndirizzo())
							&& this.getRagioneSociale().equals(
									((Scuola) o).getRagioneSociale());
			else
				return false;
		else
			return false;

	}

	public String getAbn() {
		return abn;
	}

	public User getAdder() {
		return adder;
	}

	public List<Sede> getBranches() {
		return branches;
	}

	public Sede getBranchToRemove() {
		return branchToRemove;
	}

	public String getCode() {
		return code;
	}

	public Contatto getContactToRemove() {
		return contactToRemove;
	}

	public List<ContattoScuola> getContattiDiRiferimento() {
		return contattiDiRiferimento;
	}

	public List<Corso> getCourses() {
		return courses;
	}

	public Corso getCourseToRemove() {
		return courseToRemove;
	}

	public String getCricosProviderCode() {
		return cricosProviderCode;
	}

	public String getElicosCode() {
		return elicosCode;
	}

	public List<Email> getEmails() {
		return emails;
	}

	public List<Fax> getFaxes() {
		return faxes;
	}

	public Long getId() {
		return id;
	}

	public Indirizzo getIndirizzo() {
		return indirizzo;
	}

	public Date getInsertionDate() {
		return insertionDate;
	}

	public String getRagioneSociale() {
		return ragioneSociale;
	}

	public MaterialeStudio getStudyMaterial() {
		return studyMaterial;
	}

	public List<Telephone> getTelephones() {
		return telephones;
	}

	public String getWebSite() {
		return webSite;
	}

	public boolean has(Contatto c) {
		return contattiDiRiferimento.contains(c);
	}

	public boolean has(Email au) {
		return emails.contains(au);
	}

	public boolean has(Fax fax) {
		return faxes.contains(fax);
	}

	public boolean has(Telephone tel) {
		return telephones.contains(tel);
	}

	public boolean isContrattoInCorso() {
		return contrattoInCorso;
	}

	public boolean remove(Contatto c) {
		return contattiDiRiferimento.remove(c);
	}

	public boolean remove(Email email) {
		return emails.remove(email);
	}

	public boolean remove(Fax fax) {
		return faxes.remove(fax);
	}

	public boolean remove(Telephone tel) {
		return telephones.remove(tel);
	}

	public boolean removeBranch() {
		return getBranches().remove(branchToRemove);
	}

	public boolean removeContact() {
		return getContattiDiRiferimento().remove(contactToRemove);
	}

	public boolean removeCourse() {
		return getCourses().remove(courseToRemove);
	}

	public void setAbn(String abn) {
		this.abn = abn;
	}

	public void setAdder(User adder) {
		this.adder = adder;
	}

	public void setBranches(List<Sede> branches) {
		this.branches = branches;
	}

	public void setBranchToRemove(Sede branchToRemove) {
		this.branchToRemove = branchToRemove;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public void setContactToRemove(Contatto contactToRemove) {
		this.contactToRemove = contactToRemove;
	}

	public void setContattiDiRiferimento(
			List<ContattoScuola> contattiDiRiferimento) {
		this.contattiDiRiferimento = contattiDiRiferimento;
	}

	public void setContrattoInCorso(boolean contrattoInCorso) {
		this.contrattoInCorso = contrattoInCorso;
	}

	public void setCourses(List<Corso> courses) {
		this.courses = courses;
	}

	public void setCourseToRemove(Corso courseToRemove) {
		this.courseToRemove = courseToRemove;
	}

	public void setCricosProviderCode(String cricosProviderCode) {
		this.cricosProviderCode = cricosProviderCode;
	}

	public void setElicosCode(String elicosCode) {
		this.elicosCode = elicosCode;
	}

	public void setEmails(List<Email> emails) {
		this.emails = emails;
	}

	public void setFaxes(List<Fax> faxes) {
		this.faxes = faxes;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public void setIndirizzo(Indirizzo indirizzo) {
		this.indirizzo = indirizzo;
	}

	public void setInsertionDate(Date insertionDate) {
		this.insertionDate = insertionDate;
	}

	public void setRagioneSociale(String ragioneSociale) {
		this.ragioneSociale = ragioneSociale;
	}

	public void setStudyMaterial(MaterialeStudio studyMaterial) {
		this.studyMaterial = studyMaterial;
	}

	public void setTelephones(List<Telephone> telephones) {
		this.telephones = telephones;
	}

	public void setWebSite(String webSite) {
		this.webSite = webSite;
	}

	public void setBsb(String bsb) {
		this.bsb = bsb;
	}

	public String getBsb() {
		return bsb;
	}

	public void setBank(Banca bank) {
		this.bank = bank;
	}

	public Banca getBank() {
		return bank;
	}

	public void setBankAccountNumber(String bankAccountNumber) {
		this.bankAccountNumber = bankAccountNumber;
	}

	public String getBankAccountNumber() {
		return bankAccountNumber;
	}

	public void setSpiftCode(String spiftCode) {
		this.spiftCode = spiftCode;
	}

	public String getSpiftCode() {
		return spiftCode;
	}

	public void setBankName(String bankName) {
		this.bankName = bankName;
	}

	public String getBankName() {
		return bankName;
	}

	public void setIntestatarioContoFirstName(String intestatarioContoFirstName) {
		this.intestatarioContoFirstName = intestatarioContoFirstName;
	}

	public String getIntestatarioContoFirstName() {
		return intestatarioContoFirstName;
	}

	public void setIntestatarioContoMiddleName(
			String intestatarioContoMiddleName) {
		this.intestatarioContoMiddleName = intestatarioContoMiddleName;
	}

	public String getIntestatarioContoMiddleName() {
		return intestatarioContoMiddleName;
	}

	public void setIntestatarioContoSurname(String intestatarioContoSurname) {
		this.intestatarioContoSurname = intestatarioContoSurname;
	}

	public String getIntestatarioContoSurname() {
		return intestatarioContoSurname;
	}

	public void setBankBranch(BankBranch bankBranch) {
		this.bankBranch = bankBranch;
	}

	public BankBranch getBankBranch() {
		return bankBranch;
	}

	public String getNationalProvider() {
		return nationalProvider;
	}

	public void setNationalProvider(String nationalProvider) {
		this.nationalProvider = nationalProvider;
	}

	public String getProviderCode() {
		return providerCode;
	}

	public void setProviderCode(String providerCode) {
		this.providerCode = providerCode;
	}

}
